package com.ccteam.fluidmusic.ui.user

import android.app.Application
import androidx.lifecycle.*
import com.ccteam.fluidmusic.utils.Event
import com.ccteam.fluidmusic.utils.UploadFileUtils
import com.ccteam.fluidmusic.utils.setValueIfNew
import com.ccteam.fluidmusic.view.bean.ErrorMessage
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.model.Resource
import com.ccteam.network.ApiError
import com.ccteam.shared.domain.file.UploadImageTokenDataUseCase
import com.ccteam.shared.domain.user.EditSelfInformationDataUseCase
import com.ccteam.shared.domain.user.SelfInformationDataUseCase
import com.ccteam.shared.result.user.UserInfoEditInfo
import com.orhanobut.logger.Logger
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/3/20
 *
 * 个人信息修改页面ViewModel
 */
@HiltViewModel
class SelfInformationViewModel @Inject constructor(
    application: Application,
    private val uploadImageTokenDataUseCase: UploadImageTokenDataUseCase,
    private val uploadFileUtils: UploadFileUtils,
    private val editSelfInformationDataUseCase: EditSelfInformationDataUseCase,
    private val selfInformationDataUseCase: SelfInformationDataUseCase,
    savedStateHandle: SavedStateHandle
): AndroidViewModel(application) {

    private val _uploadPhotoStatus = MutableLiveData<Event<LoadMessage>>()
    val uploadPhotoStatus: LiveData<Event<LoadMessage>> get() = _uploadPhotoStatus

    private val userId = MutableLiveData<String>()

    private val userInfoResult = MutableLiveData<Resource<UserInfoEditInfo>>(Resource.Loading())

    /**
     * 提交用户修改信息需要的加载状态UI
     */
    private val _editUserInfoLoadMessage = MutableLiveData<Event<LoadMessage>>()
    val editUserInfoLoadMessage: LiveData<Event<LoadMessage>> get() = _editUserInfoLoadMessage

    val loadMessage: LiveData<LoadMessage> = userInfoResult.map {
        when(it){
            is Resource.Success ->{
                LoadMessage.NotLoading
            }
            is Resource.Loading ->{
                LoadMessage.Loading
            }
            is Resource.Error ->{
                LoadMessage.Error(ErrorMessage(it.message,it.errorCode))
            }
        }
    }

    private val _editUserInfo = MediatorLiveData<UserInfoEditInfo>()
    val editUserInfo: LiveData<UserInfoEditInfo> get() = _editUserInfo

    init {
        _editUserInfo.addSource(userId){
            refreshUserInfo()
        }
        userId.setValueIfNew(savedStateHandle["userId"])
    }

    fun refreshUserInfo(){
        userId.value?.let {
            viewModelScope.launch {
                selfInformationDataUseCase(it).collectLatest {
                    userInfoResult.value = it

                    if(it is Resource.Success){
                        _editUserInfo.value = it.data!!
                    }
                }
            }
        }
    }

    fun setHeadPhoto(imgUri: String){
        updateHeadPhoto(imgUri)
    }

    private fun updateHeadPhoto(imgUri: String){
        val application = getApplication<Application>()
        _uploadPhotoStatus.value = Event(LoadMessage.Loading)

        // 如果选择的图片和原来的图片不符且不是空的，则上传至七牛云
        if (imgUri.isNotEmpty()
            && imgUri != _editUserInfo.value?.userImgUrl
        ) {

            viewModelScope.launch {
                val result = uploadImageTokenDataUseCase(null)

                // 检测图片上传token是否获取成功
                if (result !is Resource.Success) {
                    _uploadPhotoStatus.postValue(
                        Event(
                            LoadMessage.Error(
                                ErrorMessage("上传图片失败 get Token fail!")
                            )
                        )
                    )
                    return@launch
                }

                val token = result.data

                uploadFileUtils.upload(application,token, imgUri,
                    {}, { fileUrl ->
                        updateHeaderUrl(fileUrl)
                    }, { errorMessage ->
                        _uploadPhotoStatus.postValue(
                            Event(
                                LoadMessage.Error(
                                    ErrorMessage(errorMessage)
                                )
                            )
                        )
                    })
            }
        }
    }

    fun setUserInfo(name: String,
                    introduction: String,
                    birthday: String,
                    gender: String){
        _editUserInfo.value?.userName = name
        _editUserInfo.value?.userIntroduction = introduction
        _editUserInfo.value?.userBirthday =  birthday
        _editUserInfo.value?.userGender = gender
    }

    fun editUserInfo(
        name: String,
        introduction: String,
        birthday: String,
        gender: String
    ){
        setUserInfo(name,introduction,birthday,gender)
        if(name.isEmpty()){
            _editUserInfoLoadMessage.value = Event(LoadMessage.Error(
                ErrorMessage("用户名不能为空")
            ))
            return
        }
        if(birthday.isEmpty()){
            _editUserInfoLoadMessage.value = Event(LoadMessage.Error(
                ErrorMessage("生日未填写")
            ))
            return
        }
        if(gender.isEmpty()){
            _editUserInfoLoadMessage.value = Event(LoadMessage.Error(
                ErrorMessage("性别未选择")
            ))
            return
        }
        if(_editUserInfo.value == null){
            _editUserInfoLoadMessage.value = Event(LoadMessage.Error(
                ErrorMessage("用户操作不合法")
            ))
            return
        }
        _editUserInfoLoadMessage.value = Event(LoadMessage.Loading)

        viewModelScope.launch {
            Logger.d("修改用户信息内容：${_editUserInfo.value}")

            val result = editSelfInformationDataUseCase(
                EditSelfInformationDataUseCase.EditSelfInformationRequest(
                    id = _editUserInfo.value!!.id,userName = _editUserInfo.value!!.userName,
                    userIntroduction = _editUserInfo.value!!.userIntroduction,
                    userBirthday = _editUserInfo.value!!.userBirthday,
                    userGender = _editUserInfo.value!!.userGender
                )
            )
            if(result is Resource.Success){
                _editUserInfoLoadMessage.value = Event(LoadMessage.Success)
            } else {
                _editUserInfoLoadMessage.value = Event(LoadMessage.Error(ErrorMessage(result.message,result.errorCode)))
            }
        }
    }

    private fun updateHeaderUrl(headerUrl: String){
        _editUserInfo.value?.let {

            // 上传成功头像后获得头像路径，并更新对应头像字段
            viewModelScope.launch {
                val editResult = editSelfInformationDataUseCase(
                    EditSelfInformationDataUseCase.EditSelfInformationRequest(
                        id = it.id,
                        userImgUrl = headerUrl
                    )
                )

                if (editResult is Resource.Success) {
                    _editUserInfo.value?.userImgUrl = headerUrl
                    _editUserInfo.postValue(_editUserInfo.value)
                    _uploadPhotoStatus.postValue(Event(LoadMessage.Success))
                } else {
                    _uploadPhotoStatus.postValue(
                        Event(
                            LoadMessage.Error(
                                ErrorMessage(editResult.message, editResult.errorCode)
                            )
                        )
                    )
                }
            }
        } ?: run {
            _uploadPhotoStatus.postValue(
                Event(
                    LoadMessage.Error(
                        ErrorMessage("未知错误", ApiError.unknownCode)
                    )
                )
            )
        }
    }
}